package ru.compft.common.utils;

import org.springframework.util.StringUtils;

/**
 * User: VVasiliev
 * Date: 25.08.2011
 * Time: 14:32:42
 * <p/>
 * Конвертер строк и прочие утилиты для работы со строками
 */
public class StringConverter {
    /**
     * prefix of ascii string of native character
     */
    private static String PREFIX = "\\u";

    /**
     * Получаем первый path из строки с URI, без учета contextPath для приложения.
     * Метод нужен для сервлетов. Он помогает получить относительный путь (директорию) где физически расположен модуль.
     * Например, если URI = /setting/index.jsf, значит метод вернет - /setting. Это и будет директория на сервере приложений.
     * Именно в ней должны распологаться все необходимые файлы для модуля.
     *
     * @param uri
     * @param contextPath
     * @return
     */
    public static String getFirstPathFromUri(String uri, String contextPath) {
        if (StringUtils.hasText(uri)) {
            String result = uri;
            // если contextPath это не пустая строка - то отсекаем его совсем
            if (StringUtils.hasText(contextPath)) result = uri.replaceFirst(contextPath, "");
            final int index = result.lastIndexOf(GlobalConstants.SLASH);
            final int endIndex = index > 0 ? index : result.length();

            return result.substring(0, endIndex);
        }
        return "";
    }

    /**
     * Native to ascii string. It's same as execut native2ascii.exe
     *
     * @param str
     * @return
     */
    public static String native2Ascii(String str) {
        char[] chars = str.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (char aChar : chars) {
            sb.append(char2Ascii(aChar));
        }
        return sb.toString();
    }

    /**
     * Ascii to native string. It's same as execut native2ascii.exe -reverse.
     *
     * @param str ascii string
     * @return native string
     */
    public static String ascii2Native(String str) {
        StringBuilder sb = new StringBuilder();
        int begin = 0;
        int index = str.indexOf(PREFIX);
        while (index != -1) {
            sb.append(str.substring(begin, index));
            sb.append(ascii2Char(str.substring(index, index + 6)));
            begin = index + 6;
            index = str.indexOf(PREFIX, begin);
        }
        sb.append(str.substring(begin));
        return sb.toString();
    }

    /**
     * Ascii to native string. It's same as execut native2ascii.exe -reverse.
     *
     * @param str ascii string
     * @return native string
     */
    public static String decimal2Native(String str) {
        StringBuilder sb = new StringBuilder();
        int begin = 0;
        int index = str.indexOf(PREFIX);
        while (index != -1) {
            sb.append(str.substring(begin, index));
            sb.append(ascii2Char(str.substring(index, index + 6)));
            begin = index + 6;
            index = str.indexOf(PREFIX, begin);
        }
        sb.append(str.substring(begin));
        return sb.toString();
    }

    public static String encodeHexString(String sourceText) {
        byte[] rawData = sourceText.getBytes();
        StringBuffer hexText = new StringBuffer();
        String initialHex = null;
        int initHexLength = 0;

        for (int i = 0; i < rawData.length; i++) {
            int positiveValue = rawData[i] & 0x000000FF;
            initialHex = Integer.toHexString(positiveValue);
            initHexLength = initialHex.length();
            while (initHexLength++ < 2) {
                hexText.append("0");
            }
            hexText.append(initialHex);
        }
        return hexText.toString();
    }

    public static String decodeHexString(String hexText) {
        String decodedText = null;
        String chunk = null;

        if (hexText != null && hexText.length() > 0) {
            int numBytes = hexText.length() / 2;

            byte[] rawToByte = new byte[numBytes];
            int offset = 0;
            int bCounter = 0;
            for (int i = 0; i < numBytes; i++) {
                chunk = hexText.substring(offset, offset + 2);
                offset += 2;
                rawToByte[i] = (byte) (Integer.parseInt(chunk, 16) & 0x000000FF);
            }
            decodedText = new String(rawToByte);
        }
        return decodedText;
    }

    /**
     * Создаем запись для csv файла
     *
     * @param strArray
     * @return
     */
    public static String createCsvRecord(String[] strArray) {
        if (strArray != null) {
            final StringBuilder builder = new StringBuilder();
            for (int i = 0; i < strArray.length; i++) {
                String s = strArray[i];
                builder.append(GlobalConstants.DOUBLE_QUOTA).append(s).append(GlobalConstants.DOUBLE_QUOTA);

                // Если не последний символ, то добавим ";"
                if (i < (strArray.length - 1)) builder.append(GlobalConstants.DOT_COMMA);
            }
            // добавим символ перевода строки
            builder.append(GlobalConstants.EOL);
            return builder.toString();
        }
        return null;
    }

    /**
     * Native character to ascii string.
     *
     * @param c native character
     * @return ascii string
     */
    private static String char2Ascii(char c) {
        if (c > 255) {
            StringBuilder sb = new StringBuilder();
            sb.append(PREFIX);
            int code = (c >> 8);
            String tmp = Integer.toHexString(code);
            if (tmp.length() == 1) {
                sb.append("0");
            }
            sb.append(tmp);
            code = (c & 0xFF);
            tmp = Integer.toHexString(code);
            if (tmp.length() == 1) {
                sb.append("0");
            }
            sb.append(tmp);
            return sb.toString();
        } else {
            return Character.toString(c);
        }
    }

    /**
     * Ascii to native character.
     *
     * @param str ascii string
     * @return native character
     */
    private static char ascii2Char(String str) {
        if (str.length() != 6) {
            throw new IllegalArgumentException(
                    "Ascii string of a native character must be 6 character.");
        }
        if (!PREFIX.equals(str.substring(0, 2))) {
            throw new IllegalArgumentException(
                    "Ascii string of a native character must start with \"\\u\".");
        }
        String tmp = str.substring(2, 4);
        int code = Integer.parseInt(tmp, 16) << 8;
        tmp = str.substring(4, 6);
        code += Integer.parseInt(tmp, 16);
        return (char) code;
    }

    public static void main(String[] args) {
        for (int i = 65; i < 91; i++) {
            byte[] bytes = new byte[1];
            bytes[0] = (byte) i;
            String letter = new String(bytes);
            System.out.print(letter);
        }
        System.out.print("\n");

//        final String s = Character.toChars(1054);
//        final String s = String.copyValueOf();
//        System.out.println("s = " + s);


        // convert param-data
        final String str = "&amp;#1040;&amp;#1073;&amp;#1086;&amp;#1085;&amp;#1077;&amp;#1085;&amp;#1090;&amp;#1089;&amp;#1082;&amp;#1072;&amp;#1103;\n" +
                "            &amp;#1087;&amp;#1083;&amp;#1072;&amp;#1090;&amp;#1072;";

        final String str2 = str.replaceAll("&amp;#", "");
        final String[] strings = str2.split(";");
        StringBuilder sb = new StringBuilder();

        for (String string : strings) {
            sb.append(Character.toString((char) Integer.parseInt(string.replaceAll("\n", "").trim())));
        }

        System.out.println("sb.toString() = " + sb.toString());

        String strAsWord = "Абонентская";
        final char[] chars = strAsWord.toCharArray();
        for (char aChar : chars) {
            System.out.println("aChar = " + aChar);
        }
//    System.out.println(
//
//    decodeHexString(str.replaceAll("&amp;", "")
//
//    ));
//        System.out.println(native2Ascii("Привет всем"));

//        final int i = Integer.parseInt("1054", 16);
//        System.out.println("i = " + new String((byte) i));
    }
}
